home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Collections: Taifun
/
Taifun 135 (1990-05-15)(Ossowski, Stefan)(DE)(PD)[v Disaster Master 2].zip
/
Taifun 135 (1990-05-15)(Ossowski, Stefan)(DE)(PD)[v Disaster Master 2].adf
/
TurboMandel
/
source
/
TurboIFF.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-02-23
|
9KB
|
320 lines
/**************
* TURBOMANDEL *
**************/
/* IFF read/write */
#include <stdio.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <graphics/gfx.h>
#include <intuition/intuition.h>
#include <libraries/dos.h>
struct iff_chunk { long iff_type, iff_length; };
struct form_chunk { long fc_type, fc_length, fc_subtype; };
struct BitMapHeader {
UWORD w, h, x, y;
UBYTE nPlanes, masking, compression, pad1;
UWORD transparentColor;
UBYTE xAspect, yAspect;
WORD pageWidth, pageHeight;
};
struct ILBM_info {
struct BitMapHeader header;
struct BitMap bitmap;
UBYTE cmap[96];
};
extern struct MandelChunk {
ULONG XCoo[2], YCoo[2], XSide[2], YSide[2];
UWORD Iteration;
UBYTE Calculation, Flags;
SHORT TopPos[3], DecrStep[3], ColInt[3];
} MandChunk;
read_iff (info, name, just_header)
struct ILBM_info *info;
char *name;
int just_header;
{
UBYTE bool;
FILE *file;
struct form_chunk chunk;
if ((file = fopen (name, "r") ) == 0) return (FALSE);
if (fread (&chunk, sizeof (struct form_chunk), 1, file) != 1) {
fclose (file); return (FALSE);
}
if (chunk.fc_type != 'FORM' || chunk.fc_subtype != 'ILBM') {
fclose (file); return (FALSE);
}
bool = read_ilbm (file, info, chunk.fc_length - sizeof (chunk), just_header);
fclose (file);
return ((int)bool);
}
read_ilbm (file, info, length, just_header)
FILE *file;
struct ILBM_info *info;
long length;
int just_header;
{
struct iff_chunk chunk;
long read_in = 0;
int got_header = FALSE, got_cmap = FALSE;
while (read_in < length) {
if (fread (&chunk, sizeof (chunk), 1, file) != 1) return (FALSE);
switch (chunk.iff_type) {
case 'BMHD':
if (fread (&info->header, sizeof(info->header), 1, file) != 1)
return (FALSE);
got_header = TRUE;
break;
case 'MANC': /* read mandel chunk */
if (fread (&MandChunk, sizeof(MandChunk), 1, file) != 1)
return (FALSE);
break;
case 'CMAP':
if (!got_header) return (FALSE);
if (chunk.iff_length <= 96) {
if (fread (info->cmap, (int)chunk.iff_length, 1, file) != 1)
return (FALSE);
}
else {
if (fread(info->cmap, 96, 1, file) != 1) return (FALSE);
fseek (file, (long)chunk.iff_length - sizeof (3 * 32), 1);
}
got_cmap = TRUE;
break;
case 'BODY':
if (!got_cmap || !got_header) return (FALSE);
if (just_header) return (TRUE);
return (read_body (file, info, chunk.iff_length));
default:
fseek (file, (long)chunk.iff_length, 1);
break;
}
read_in += chunk.iff_length + sizeof(chunk);
}
return (FALSE);
}
read_body (file, info, length)
FILE *file;
register struct ILBM_info *info;
long length;
{
long i, j, plane_offset;
if (info->header.compression != 0 && info->header.compression != 1)
return (FALSE);
plane_offset = 0;
for (i = 0; i < info->bitmap.Rows; i++) {
if (info->header.compression == 0) {
for (j = 0; j < info->bitmap.Depth; j++)
if (fread(info->bitmap.Planes[j] + plane_offset,
info->bitmap.BytesPerRow, 1, file) != 1) return(FALSE);
}
else {
register char *dest, value;
register int so_far, count;
for (j = 0; j < info->bitmap.Depth; j++) {
so_far = info->bitmap.BytesPerRow;
dest = (char *)info->bitmap.Planes[j] + plane_offset;
while (so_far > 0) {
value = getc (file);
if (value > 0 && value != 128) {
count = (int)value + 1;
so_far -= count;
if (fread (dest, count, 1, file) != 1) return (FALSE);
dest += count;
}
else {
count = (int)-value + 1;
so_far -= count;
value = getc (file);
while (--count >= 0) *dest++ = value;
}
}
if (so_far != 0) return (FALSE);
}
}
plane_offset += info->bitmap.BytesPerRow;
}
return (TRUE);
}
#define DUMP 0
#define RUN 1
ULONG pack_row (source, dest, size)
char *source, *dest;
int size;
{
char c, lastc = 0, *olddest;
short mode = DUMP, nbuf = 0, rstart = 0, i;
char buf[128*3/2];
olddest = dest;
buf[0] = lastc = *source++;
nbuf = 1; size--;
for (; size; --size) {
buf[nbuf++] = c = *source++;
if (mode == DUMP) {
if (nbuf > 128) {
*dest++ = nbuf - 2;
for (i = 0; i < nbuf-1; i++) *dest++ = buf[i];
buf[0] = c; nbuf = 1; rstart = 0;
}
else if (c == lastc) {
if (nbuf - rstart >= 3) {
if (rstart > 0) {
*dest++ = rstart - 1;
for (i = 0; i < rstart; i++) *dest++ = buf[i];
}
mode = RUN;
}
else if (rstart == 0) mode = RUN;
}
else rstart = nbuf - 1;
}
else {
if ((c != lastc) || (nbuf - rstart > 128)) {
*dest++ = - (nbuf - rstart - 2); *dest++ = lastc;
buf[0] = c; nbuf = 1; rstart = 0; mode = DUMP;
}
}
lastc = c;
}
if (mode == DUMP) {
*dest++ = nbuf - 1;
for (i = 0; i < nbuf; i++) *dest++ = buf[i];
}
else {
*dest++ = - nbuf + rstart + 1; *dest++ = lastc;
}
return ((ULONG)(dest - olddest));
}
ULONG pack_bitmap (file, bm)
FILE *file;
struct BitMap *bm;
{
char packbuffer[256];
int i, j, row_length;
ULONG compressed_length = 0, plane_offset = 0;
for (i = 0; i < bm->Rows; i++) {
for (j = 0; j < bm->Depth; j++) {
row_length = pack_row
(bm->Planes[j] + plane_offset, packbuffer, bm->BytesPerRow);
if (file) if (fwrite(packbuffer, row_length, 1, file) != 1) return (0);
compressed_length += row_length;
}
plane_offset += bm->BytesPerRow;
}
if (compressed_length & 1) {
if (file) if (putc (0, file) == EOF) return(0);
compressed_length++;
}
return (compressed_length);
}
int write_iff (name, colors, scr, compressed)
char *name;
UWORD *colors;
struct Screen *scr;
int compressed;
{
struct BitMap *bits;
struct form_chunk chunk;
struct iff_chunk ichunk;
struct BitMapHeader header;
UBYTE rgbcolors[96];
SHORT i, numcols, j, row_offset;
ULONG bits_size, viewmodes;
FILE *file;
if ((file = fopen (name, "w") ) == 0) return(0);
if (scr) {
bits = &scr->BitMap;
if ((numcols = (1 << bits->Depth)) > 32) numcols = 32;
}
else numcols = 32;
chunk.fc_type = 'FORM'; chunk.fc_subtype = 'ILBM';
chunk.fc_length = 4 + 3 * sizeof (struct iff_chunk) + 12 + 62 +
numcols * 3 + sizeof(struct BitMapHeader);
if (scr) {
if (compressed) {
if ((bits_size = pack_bitmap (NULL, bits)) == 0) return(0);
}
else bits_size = bits->BytesPerRow * bits->Rows * bits->Depth;
chunk.fc_length += bits_size;
}
if (fwrite (&chunk, sizeof(chunk), 1, file) != 1) return(0);
ichunk.iff_type = 'BMHD';
ichunk.iff_length = sizeof(header);
if (fwrite (&ichunk, sizeof(ichunk), 1, file) != 1) return(0);
header.masking = header.pad1 = header.transparentColor = 0;
header.compression = compressed;
header.pageWidth = bits->BytesPerRow * 8;
header.pageHeight = bits->Rows;
header.xAspect = header.yAspect = 10;
/* write bitmapheader */
if (scr) {
header.w = bits->BytesPerRow * 8;
header.h = bits->Rows;
header.nPlanes = bits->Depth;
header.x = header.y = 0;
}
if (fwrite (&header, sizeof(header), 1, file) != 1) return(0);
/* write camg */
ichunk.iff_type = 'CAMG'; ichunk.iff_length = 4;
if (fwrite (&ichunk, sizeof(ichunk), 1, file) != 1) return(0);
viewmodes = (ULONG)scr->ViewPort.Modes;
if (fwrite (&viewmodes, 4, 1, file) != 1) return(0);
/* write cmap */
ichunk.iff_type = 'CMAP'; ichunk.iff_length = numcols * 3;
if (fwrite (&ichunk, sizeof(ichunk), 1, file) != 1) return(0);
for (i = 0; i < numcols; i++) {
rgbcolors[3 * i] = (colors[i] & 0xf00) >> 4;
rgbcolors[3 * i + 1] = (colors[i] & 0x0f0);
rgbcolors[3 * i + 2] = (colors[i] & 0x00f) << 4;
}
if (fwrite (&rgbcolors[0], numcols * 3, 1, file) != 1) return(0);
/* write mandel chunk */
ichunk.iff_type = 'MANC'; ichunk.iff_length = sizeof(MandChunk);
if (fwrite (&ichunk, sizeof(ichunk), 1, file) != 1) return(0);
if (fwrite (&MandChunk, sizeof(MandChunk), 1, file) != 1) return (0);
if (scr) {
ichunk.iff_type = 'BODY'; ichunk.iff_length = bits_size;
if (fwrite(&ichunk, sizeof(ichunk), 1, file) != 1) return(0);
if (compressed) {
if (pack_bitmap(file, bits) == 0) return(0);
}
else {
i = bits->Rows;
row_offset = 0;
while (--i >= 0) {
for (j = 0; j < bits->Depth; j++)
if (fwrite( bits->Planes[j]+row_offset, bits->BytesPerRow,
1, file) != 1) return(0);
row_offset += bits->BytesPerRow;
}
}
}
fclose (file);
return (1);
}